<template>
  <view>
    <image
      :src="image.src"
      @click="handleSelectImage"
      :style="[imageStyle]"
      class="h-avatar"
    ></image>
  </view>
</template>

<script setup lang="ts">
interface AvatarProps {
  /**
   * 头像的图片源路径，对应原字段：avatarSrc
   */
  avatarSource: string

  /**
   * 头像的自定义样式，对应原字段：avatarStyle
   */
  avatarStyle: string

  /**
   * 图片裁剪区域的宽度，对应原字段：selWidth
   */
  selectionWidth: string

  /**
   * 图片裁剪区域的高度，对应原字段：selHeight
   */
  selectionHeight: string

  /**
   * 导出的图片宽度，对应原字段：expWidth
   */
  exportWidth: string

  /**
   * 导出的图片高度，对应原字段：expHeight
   */
  exportHeight: string

  /**
   * 允许缩放的最小比例，对应原字段：minScale
   */
  minimumScale: string

  /**
   * 允许缩放的最大比例，对应原字段：maxScale
   */
  maximumScale: string

  /**
   * 是否允许图片缩放，对应原字段：canScale
   */
  isScalable: boolean

  /**
   * 是否允许图片旋转，对应原字段：canRotate
   */
  isRotatable: boolean

  /**
   * 锁定图片宽度，对应原字段：lockWidth
   */
  lockedWidth: string

  /**
   * 锁定图片高度，对应原字段：lockHeight
   */
  lockedHeight: string

  /**
   * 是否允许拉伸图片，对应原字段：stretch
   */
  isStretchable: boolean

  /**
   * 是否锁定图片比例，对应原字段：lock
   */
  isLocked: boolean

  /**
   * 文件类型（例如：png、jpg），对应原字段：fileType
   */
  fileType: string

  /**
   * 是否隐藏 Tab 导航栏，对应原字段：noTab
   */
  hideTabBar: boolean

  /**
   * 是否为内嵌模式，对应原字段：inner
   */
  isInnerMode: boolean

  /**
   * 图片的导出质量（范围 0 - 100），对应原字段：quality
   */
  imageQuality: number

  /**
   * 当前组件的索引值，对应原字段：index
   */
  componentIndex: number

  /**
   * 画布背景图片的路径，对应原字段：bgImage
   */
  backgroundImageSource: string
}
const props = defineProps<AvatarProps>()
// tabbar的高度
const tabBarHeight = 50
// 画布的高度，初始为 "0px"。对应原字段：csH
const canvasHeight = ref<string>('0px')
// 画布的显示状态，初始为 "none"。对应原字段：sD
const displayState = ref<string>('none')
// 画布的顶部偏移，初始为 "-10000px"，用于隐藏画布。对应原字段：sT
const topOffset = ref<string>('-10000px')
// 预览框的顶部偏移，初始为 "-10000px"，用于隐藏预览。对应原字段：pT
const previewTopOffset = ref<string>('-10000px')
// 图片的初始状态对象，用于存储图片相关信息。对应原字段：iS
const imageState = ref<any>({})
// 选区的状态对象，用于存储裁剪选区的相关信息。对应原字段：sS
const selectionState = ref<any>({})
// 画布的显示开关，初始为 true。用于控制画布是否显示。对应原字段：sO
const showCanvas = ref<boolean>(true)
// 按钮宽度的百分比，初始为 "19%"。对应原字段：bW
const buttonWidth = ref<string>('19%')
// 按钮的显示方式，初始为 "flex"。对应原字段：bD
const buttonDisplay = ref<string>('flex')
// 当前画布距离顶部的偏移量，初始为 0。对应原字段：tp
const canvasTop = ref<string>('0px')
// 当前的旋转角度，初始为 0。对应原字段：tp
const rotationAngle = ref<number>(0)
// 图片源路径对象，包含一个 imgSrc 属性，初始为空字符串。对应原字段：imgSrc
const image = ref<any>({ src: '' })
// 平台信息，初始为空字符串。用于存储当前平台信息。
const platform = ref<string>('')
// 窗口的宽度，初始为 0。
const windowWidth = ref<number>(0)

// 窗口的高度，初始为 0。
const windowHeight = ref<number>(0)

// 画布顶部的偏移量，初始为 0。
const drawTop = ref<number>(0)

// 导出图片的宽度，初始为 0。
const exportWidthRef = ref<number>(0)

// 导出图片的高度，初始为 0。
const exportHeightRef = ref<number>(0)

// 像素比率，初始为 0，用于计算不同屏幕下的尺寸转换。
const pxRatio = ref<number>(0)

// 是否正在选择图片，初始为 false。
const isSelecting = ref<boolean>(false)
// 是否选中图片，初始为 false。
const isSelected = ref<boolean>(false)

// 图片路径
const imagePath = ref<string>('')
// 图片宽度
const imageWidth = ref<number>(0)
// 图片高度
const imageHeight = ref<number>(0)

// 从 props 中解构获取的属性，方便后续使用。
const { avatarSource, avatarStyle, exportWidth, exportHeight, hideTabBar } = props

watch(
  () => props.avatarSource,
  (value) => {
    image.value.src = value
  },
  { immediate: true },
)

// 监听窗口大小变化事件，用于更新画布的尺寸。
const onWindowResize = () => {
  const sysInfo = uni.getSystemInfoSync()
  platform.value = sysInfo.platform
  windowWidth.value = sysInfo.windowWidth

  // #ifdef H5
  drawTop.value = sysInfo.windowTop
  // #endif
  // #ifndef H5
  drawTop.value = 0
  // #endif

  // #ifdef MP-ALIPAY
  windowHeight.value = sysInfo.screenHeight - sysInfo.statusBarHeight
  canvasHeight.value = `${windowHeight.value}px`
  // #endif

  // #ifndef MP-ALIPAY
  windowHeight.value = sysInfo.windowHeight
  if (!hideTabBar) {
    windowHeight.value += tabBarHeight
  }
  canvasHeight.value = windowHeight.value - tabBarHeight + 'px'
  // #endif

  canvasTop.value = canvasHeight.value

  // #ifdef H5
  canvasTop.value = sysInfo.windowTop + parseInt(canvasHeight.value) + 'px'
  // #endif

  pxRatio.value = sysInfo.windowWidth / 750

  let style = avatarStyle
  if (style && (style = style.trim())) {
    const styleArray = style.split(';') // 使用新的变量名
    const styleObject: { [key: string]: string } = {} // 确保 obj 的类型
    for (const styleItem of styleArray) {
      if (!styleItem) continue
      const stylePair = styleItem.trim().split(':')
      if (stylePair[1].toString().indexOf('upx') >= 0) {
        const valueArray = stylePair[1].trim().split(' ')
        for (const key in valueArray) {
          if (!valueArray[key]) continue
          if (valueArray[key].toString().indexOf('upx') >= 0) {
            valueArray[key] = parseFloat(valueArray[key]) * pxRatio.value + 'px'
          }
        }
        stylePair[1] = valueArray.join(' ')
      }
      styleObject[stylePair[0].trim()] = stylePair[1].trim()
    }
    imageState.value = styleObject
  }
}

// 选择图片
const handleSelectImage = () => {
  if (isSelecting.value) return
  isSelecting.value = true

  // 500ms 后重置 isSelected 的值
  setTimeout(() => {
    isSelecting.value = false
  }, 500)

  // 调用 uni.chooseImage 选择图片
  uni.chooseImage({
    count: 1, // 选择的图片数量
    sizeType: ['original', 'compressed'], // 图片的尺寸类型
    sourceType: ['album', 'camera'], // 图片的来源：相册或相机
    success: (res) => {
      // 显示加载提示
      // #ifdef MP-ALIPAY
      uni.showLoading()
      // #endif
      // #ifndef MP-ALIPAY
      uni.showLoading({
        title: '加载中...',
        mask: true,
      })
      // #endif
      // 获取选中图片的路径
      const tempFilePaths = (image.value.src = res.tempFilePaths[0])
      // 获取图片信息
      uni.getImageInfo({
        src: tempFilePaths,
        success: (imgInfoRes) => {
          imageWidth.value = imgInfoRes.width
          imageHeight.value = imgInfoRes.height
          imagePath.value = tempFilePaths

          if (!isSelected.value) {
            const style = imageState.value.style || {}
            if (props.selectionWidth && props.selectionHeight) {
              // 根据选择框的宽高设置样式
              const selectWidth = props.selectionWidth.toString().includes('upx')
                ? parseInt(props.selectionWidth) * pxRatio.value + 'px'
                : parseInt(props.selectionWidth)
              const selectHeight = props.selectionHeight.toString().includes('upx')
                ? parseInt(props.selectionHeight) * pxRatio.value + 'px'
                : parseInt(props.selectionHeight)
              // 设置样式
              style.width = selectWidth + 'px'
              style.height = selectHeight + 'px'
              style.top = (windowHeight.value - Number(selectHeight)) / 2 + 'px'
              style.left = (windowWidth.value - Number(selectWidth)) / 2 + 'px'
            } else {
              uni.showModal({
                title: '裁剪框的宽或高没有设置',
                showCancel: false,
              })
              return
            }
            imageState.value.style = style
          }

          // 根据是否隐藏 TabBar 初始化画布
          if (hideTabBar) {
            handleDrawInit(true)
          } else {
            uni.hideTabBar({
              complete: () => {
                handleDrawInit(true)
              },
            })
          }
        },
        fail: (fail) => {
          console.log(fail)
          uni.showToast({
            title: '请选择正确的图片',
            duration: 2000,
          })
        },
        complete: () => {
          uni.hideLoading()
        },
      })
    },
  })
}

// 绘制图片
const handleDrawInit = (ini: boolean = false) => {}
</script>
